package com.lora.service.resolver;

import com.google.common.base.Splitter;
import com.lora.common.ColumnParse;
import com.lora.dto.EquipmentDto;
import com.lora.entity.Ups;
import com.lora.service.NodeDataResolver;
import com.lora.service.UpsService;
import com.lora.web.BaseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;

@Slf4j
@Component("upsResolver")
public class UpsResolver implements NodeDataResolver<Ups> {

    @Resource
    private UpsService upsService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public EquipmentDto<Ups> resolve(String equipmentNumber, String data) {
        data = BaseUtil.base64ToHex(data);
        data = this.parseUpsData(equipmentNumber, data);
        if(StringUtils.isBlank(data)) {
            return null;
        }
        EquipmentDto<Ups> equipmentDto = new EquipmentDto<>();
        //String modBusData = data.substring(6);
        //String responseData = modBusData; // modBusData.substring(16); 如果不使用机房卫士则没有请求的数据
        String businessData = data; // responseData.substring(6, responseData.length() - 4);
        Iterable<String> split = Splitter.fixedLength(4).split(businessData);
        Iterator<String> iterator = split.iterator();
        int index = 1;
        Ups ups = new Ups();
        ups.setEquipmentid(equipmentNumber);
        ups.setDatastring(data);
        Field[] declaredFields = ups.getClass().getDeclaredFields();
        while(iterator.hasNext()) {
            int finalIndex = index;
            index ++;
            String splitData = iterator.next();
            Field field = Arrays.asList(declaredFields).stream().filter(v -> {
                ColumnParse annotation = v.getAnnotation(ColumnParse.class);
                if (annotation != null) {
                    if (annotation.seq() == finalIndex) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }).findAny().orElse(null);
            if(field != null) {
                ColumnParse annotation = field.getAnnotation(ColumnParse.class);
                field.setAccessible(true);
                try {
                    field.set(ups, new BigDecimal(Integer.parseInt(splitData, 16)).multiply(new BigDecimal(annotation.ratio())));
                } catch (IllegalAccessException e) {
                    log.error("解析UPS数据{}出错:{}", field.getName(), e);
                }
            }
        }
        equipmentDto.setEntity(ups);
        return equipmentDto;
    }

    @Override
    public Ups save(Ups equipment, boolean alarmFlag) {
        equipment.setAlarmFlag(alarmFlag);
        upsService.save(equipment);
        return equipment;
    }

    private String parseUpsData(String equipmentNumber, String data) {
        data = data.substring(6);
        String query = data.substring(0, 6);
        data = data.substring(6, data.length() - 4);
        redisTemplate.opsForHash().put(equipmentNumber, query, data);
        // 010370 查询03码电压电流相关
        // 010442 查询04码状态相关
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(equipmentNumber);
        if(entries.containsKey("010370") && entries.containsKey("010442")) {
            String firstData = (String) redisTemplate.opsForHash().get(equipmentNumber,"010370");
            String secondData = (String) redisTemplate.opsForHash().get(equipmentNumber,"010442");
            redisTemplate.opsForHash().delete(equipmentNumber,"010370");
            redisTemplate.opsForHash().delete(equipmentNumber,"010442");
            return firstData + secondData;
        }
        return null;
    }

    /*@Override
    public String alarm(Ups equipment, String alarmConfig) throws IllegalAccessException {
        List<String> alarmGroups = Lists.newArrayList();
        JSONObject object = JSONObject.parseObject(alarmConfig);
        String field = object.getString("field");
        String epName = object.getString("epName");
        String title = object.getString("title");
        String type = object.getString("valueType");
        JSONArray array = object.getJSONArray("checks");
        Field[] declaredFields = equipment.getClass().getDeclaredFields();
        if("BigDecimal".equals(type)) {
            CheckItem<BigDecimal> item = new CheckItem<>();
            item.setEquipmentName(epName);
            item.setFiledName(field);
            item.setFiledTitle(title);
            Field field1 = Arrays.asList(declaredFields).stream().filter(v -> v.getName().equals(field)).findFirst().orElse(null);
            if(field1 != null) {
                for(Object obj : array) {
                    field1.setAccessible(true);
                    Object o = field1.get(equipment);
                    JSONObject object1 = JSONObject.parseObject(obj.toString());
                    item.setCheckObject((BigDecimal) o);
                    item.setStandard(new BigDecimal(object1.getString("standard")));
                    item.setCheckAlgorithm(object1.getString("algorithm"));
                    String alarm = item.check();
                    if(StringUtils.isNotBlank(alarm)) {
                        alarmGroups.add(alarm);
                    }
                }
            }
        }
        return StringUtils.join(alarmGroups, ",");
    }*/

    public static void main(String[] args) throws IllegalAccessException {
        /*String data = "04032301030001003815d80103700956094e0955000000000000138913891389006400640064094e0951094a000f000e001013891389138900590059005a08ae08af08aa001400210000138813881388003500510004000200070000000200060000000000030000004800dc000000fa087708780001000000fa7ff803e827bc";
        String sensorBoxFlag = data.substring(0, 6);
        String modbusData = data.substring(6);
        String requestData = modbusData.substring(0, 16);
        String responseData = modbusData.substring(16);
        String busiData = responseData.substring(6, responseData.length() - 4);
        Iterable<String> split = Splitter.fixedLength(4).split(busiData);
        Iterator<String> iterator = split.iterator();
        int index = 1;

        Ups ups = new Ups();
        Field[] declaredFields = ups.getClass().getDeclaredFields();
        while(iterator.hasNext()) {
            int finalIndex = index;
            index ++;
            String splitData = iterator.next();
            // System.out.println((index++) + ":" + splitData + ":" + Integer.parseInt(splitData, 16));
            Field field = Arrays.asList(declaredFields).stream().filter(v -> {
                ColumnParse annotation = v.getAnnotation(ColumnParse.class);
                if (annotation != null) {
                    if (annotation.seq() == finalIndex) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }).findAny().orElse(null);
            ColumnParse annotation = field.getAnnotation(ColumnParse.class);
            field.setAccessible(true);
            field.set(ups, new BigDecimal(Integer.parseInt(splitData, 16)).multiply(new BigDecimal(annotation.ratio())));
        }
        System.out.println(ups.toString());*/
    }

}
